package com.drcoffee.drcoffeemall.service.impl;

import com.drcoffee.drcoffeemall.entry.*;
import com.drcoffee.drcoffeemall.mapper.PartsMapper;
import com.drcoffee.drcoffeemall.mapper.CollectMapper;
import com.drcoffee.drcoffeemall.mapper.UserMapper;
import com.drcoffee.drcoffeemall.service.CollectService;
import com.drcoffee.drcoffeemall.util.DiscountedPriceUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;

@Slf4j
@Service
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
public class CollectServiceImpl implements CollectService {

    final
    CollectMapper collectMapper;

    final
    UserMapper userMapper;

    final
    PartsMapper partsMapper;


    final
    RedisTemplate<String, Object> redisTemplate;

    public CollectServiceImpl(CollectMapper collectMapper, UserMapper userMapper, PartsMapper partsMapper, RedisTemplate<String, Object> redisTemplate) {
        this.collectMapper = collectMapper;
        this.userMapper = userMapper;
        this.partsMapper = partsMapper;
        this.redisTemplate = redisTemplate;
    }


    @Override
    public Result getCollect(String Token, String search, String language) {
        try {
            User user = (User) redisTemplate.opsForValue().get(Token);

            if (user != null) {
                String price_type = getPriceType("c", user);
                List<Attachment> attachmentList = collectMapper.getCollect(user.getAccount(), '%' + search + '%', price_type, language);

                // 特价条件：国内企业用户 && 没有折扣
                List<SpecialPrice> specialPrice = null;
                if (user.getPermission_id() == 1 && (user.getDiscount_one().compareTo(BigDecimal.ZERO) == 0 || user.getDiscount_two().compareTo(BigDecimal.ZERO) == 0)) {
                    specialPrice = partsMapper.getSpecialPrice(user.getErp_code());
                }
                for (Attachment attachment : attachmentList) {
                    /* 价格处理 */
                    // 折后价格
                    BigDecimal discountedPrice = DiscountedPriceUtil.getDiscountedPrice(attachment.getPrice(), user);
                    attachment.setDiscounted_price(discountedPrice);
                    if (specialPrice != null) {
                        for (SpecialPrice special : specialPrice) {
                            if (Objects.equals(special.getPart_code(), attachment.getPart_code())) {
                                attachment.setDiscounted_price(special.getPrice());
                            }
                        }
                    }
                    // 小计价格
                    BigDecimal price = attachment.getDiscounted_price().multiply(BigDecimal.valueOf(attachment.getQuantity()));
                    attachment.setSubtotal(price);
                }
                return new Result(1, "SUCCESS", "", attachmentList);
            } else {
                return new Result(-1, "ERROR", "user is null", null);
            }
        } catch (Exception e) {
            log.error("===================== getCollect()异常： =====================", e);
            return new Result(-1, "ERROR", e.getMessage(), null);
        }
    }

    @Override
    public Result addToCollect(String Token, Attachment attachment) {
        User user = (User) redisTemplate.opsForValue().get(Token);
        try {
            if (user != null) {
                List<Collect> CollectList = collectMapper.getCollectByattachment_id(user.getAccount(), attachment.getPart_code());
                if (!CollectList.isEmpty()) {
                    Integer quantity = attachment.getQuantity() + CollectList.get(0).getQuantity();
                    attachment.setQuantity(quantity);
                    updateQuantityById(user.getAccount(), attachment);
                } else {
                    Collect Collect = new Collect();
                    Collect.setPart_code(attachment.getPart_code());
                    Collect.setQuantity(attachment.getQuantity());
                    Collect.setUser_account(user.getAccount());
                    collectMapper.addToCollect(Collect);
                }
                return new Result(1, "SUCCESS", "Successfully added to Collect", null);
            } else {
                return new Result(-1, "ERROR", "User is Null", null);
            }
        } catch (Exception e) {
            log.error("===================== addToCollect()异常： =====================", e);
            return new Result(-1, "ERROR", e.getMessage(), null);
        }
    }

    @Override
    public Result removeFromCart(String Token, List<String> part_code) {
        try {
            User user = (User) redisTemplate.opsForValue().get(Token);
            if (user != null) {
                collectMapper.deletePartByCode(user.getAccount(), part_code);
                return new Result(1, "SUCCESS", "Successfully deleted", null);
            } else {
                return new Result(-1, "ERROR", "user is null", null);
            }
        } catch (Exception e) {
            log.error("===================== deletePartByCode()异常： =====================", e);
            return new Result(-1, "ERROR", e.getMessage(), null);
        }
    }

    @Override
    public Result updateQuantityById(String account, Attachment attachment) {
        try {
            Collect Collect = new Collect();
            Collect.setQuantity(attachment.getQuantity());
            Collect.setUser_account(account);
            Collect.setPart_code(attachment.getPart_code());
            collectMapper.updateQuantityById(Collect);
            return new Result(1, "SUCCESS", "", null);
        } catch (Exception e) {
            log.error("===================== updateQuantityById()异常： =====================", e);
            return new Result(-1, "ERROR", e.getMessage(), null);
        }
    }

    /*
     * 根据料号、数量、用户类型、折扣 计算总价格
     * */
    @Override
    public ResponseEntity<Object> getTotal(String Token, List<String> part_codes) {
        Map<String, Object> resultMap = new HashMap<>();
        User user = (User) redisTemplate.opsForValue().get(Token);

        List<ProductQuantity> checkPartList = collectMapper.getCollectByAccountAndPartCodes(user.getAccount(), part_codes);

        String price_type = getPriceType("b", user);
        // 特价条件：国内企业用户 && 没有折扣
        List<SpecialPrice> specialPrice = null;
        if (user.getPermission_id() == 1 && (user.getDiscount_one().compareTo(BigDecimal.ZERO) == 0 || user.getDiscount_two().compareTo(BigDecimal.ZERO) == 0)) {
            specialPrice = partsMapper.getSpecialPrice(user.getErp_code());
        }
        /* 价格处理 */
        // 折前合计价格
        BigDecimal beforeTotal = new BigDecimal(0);
        // 折后合计价格
        BigDecimal total = new BigDecimal(0);
        for (ProductQuantity checkPart : checkPartList) {
            String language;
            if (user.getPermission_id() == 2) {
                language = "EN";
            } else {
                language = "CN";
            }
            Attachment attachment = partsMapper.getAttachmentByPartCode(checkPart.getPart_code(), price_type, language);
            // 折前小计
            BigDecimal beforePrice = attachment.getPrice().multiply(BigDecimal.valueOf(checkPart.getQuantity()));
            System.out.println(checkPart.getPart_code() + "-" + checkPart.getQuantity() + "-" + beforePrice);
            beforeTotal = beforeTotal.add(beforePrice);
            // 折后价格
            BigDecimal bigDecimal = DiscountedPriceUtil.getDiscountedPrice(attachment.getPrice(), user);
            // 判断该用户是否存在商品特殊价格
            if (specialPrice != null) {
                for (SpecialPrice special : specialPrice) {
                    if (Objects.equals(special.getPart_code(), checkPart.getPart_code())) {
                        bigDecimal = special.getPrice();
                    }
                }
            }
            // 小计 (* 数量)
            BigDecimal price = bigDecimal.multiply(BigDecimal.valueOf(checkPart.getQuantity()));
            System.out.println(checkPart.getPart_code() + "-" + checkPart.getQuantity() + "-" + price);
            total = total.add(price);
        }
        BigDecimal decrease = beforeTotal.subtract(total);
        // 合计价格
        resultMap.put("total", total);
        // 优惠 -￥
        resultMap.put("decrease", decrease);
        return new ResponseEntity<>(resultMap, HttpStatus.OK);
    }

    /* 获取价格类型字段 */
    private static String getPriceType(String another, User user) {
        String price_type = "";
        Integer permission_id = user.getPermission_id();
        if (permission_id == 0 || permission_id == 3) {
            // 0 零售 price
            price_type = another + ".price";
        } else if (permission_id == 1) {
            // 1 内销 dealer_price
            price_type = another + ".dealer_price as price";
        } else if (permission_id == 2) {
            // 2 外销 overseas_price
            price_type = another + ".overseas_price as price";
        }
        return price_type;
    }

}
